from openai import OpenAI
from typing import Callable
from collections import namedtuple
from qfluentwidgets import TeachingTip,InfoBarIcon,TeachingTipTailPosition

import qianfan
from volcenginesdkarkruntime._streaming import Stream
from volcenginesdkarkruntime.types.chat.chat_completion_chunk import ChatCompletionChunk
auth = namedtuple("authconfig",["sk","type"])
class AgentType():
    Qwen ="千问"
    DeepSeek ="DeepSeek"
    Kimi ="Kimi"

ModelMap = {
    "千问":["qwen-turbo","qwen-plus","qwen-long","qwen-max"],
    "DeepSeek":["deepseek-chat","deepseek-coder"],
    "Kimi":["moonshot-v1-8k","moonshot-v1-32k"],
    "混元":["hunyuan-lite","hunyuan-standard"],
    "千帆":["ERNIE-Lite-8K","ERNIE-Speed-128K","Qianfan-Chinese-Llama-2-7B","CodeLlama-7B-Instruct"],
    "豆包":["Doubao-lite-4k","Doubao-lite-32k","Doubao-pro-4k"]}
urlMap = {"千问":"https://dashscope.aliyuncs.com/compatible-mode/v1",
          "DeepSeek":"https://api.deepseek.com",
          "Kimi":"https://api.moonshot.cn/v1"}


def showMessage(ty:str,s:str,p=None,target=None):
    TeachingTip.create(
            target=target, # type: ignore
            icon=InfoBarIcon.SUCCESS,
            title=ty,
            content=s,
            isClosable=True,
            tailPosition=TeachingTipTailPosition.BOTTOM_RIGHT,
            duration=2000,
            parent=p
        )
class openai:
    def __init__(self,a:auth) -> None:
        self.key =a.sk
        self.url =urlMap[a.type]
        self.client = OpenAI(api_key=self.key,base_url=self.url)
        self.history = [{'role': 'system', 'content': 'You are a helpful assistant.'}]
        self.model = ModelMap[a.type][0]
        self.isMulti = False
    def setModel(self,s:str):
        self.model = s


    def StreamCall(self,s:str,fn:Callable[[str],None]):
        if not self.isMulti:
            self.history = []
        self.history.append({'role': 'user', 'content': f'{s}'})
        cmp = self.client.chat.completions.create(
        model=self.model,
        messages=self.history, # type: ignore
        stream=True
        )
        temp = ""
        for chunk in cmp:
            ctx = chunk.choices[0].delta.content 
            try:
                if len(ctx)>0:
                    fn(ctx)
            except Exception as e:
                showMessage("错误",f"{e=}",None,None)
            temp +=ctx
        if self.isMulti:
            self.history.append({'role': 'system', 'content': f'{temp}'})


class qf:
    def __init__(self,sk=None,ak=None) -> None:
        if sk==None or ak==None:
            raise ValueError(f"{sk=},{ak=} is invalid")
        self.client = qianfan.ChatCompletion(ak=ak,sk=sk)
        self.model = ModelMap["千帆"][0]
        self.history = []
        self.isMulti =False
    def setModel(self,s:str):
        self.model = s
    def StreamCall(self,s:str,fn:Callable[[str],None]):
        temp = ""
        if not self.isMulti:
            self.history = []
        self.history.append({"role":"user","content":f"{s}"})
        resp = self.client.do(model=self.model,messages=self.history,stream=True)
        for chunk in resp:
            ctx = chunk["body"]["result"] 
            try:
                if len(ctx)>0:
                    fn(ctx)
            except Exception as e:
                showMessage("错误",f"{e=}",None,None)
            temp +=ctx
        if self.isMulti:
            self.history.append({'role': 'system', 'content': f'{temp}'})

import json

from tencentcloud.common.common_client import CommonClient
from tencentcloud.common import credential
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile



class hy:
    def __init__(self,sk=None,ak=None) -> None:
        if sk==None or ak==None:
            raise ValueError(f"{sk=},{ak=} is invalid")
        self.model = ModelMap["混元"][0]
        self.message = {"Messages":[],"Stream":True,"Model":self.model}
        self.history =self.message["Messages"]
        self.isMulti =False      
        cred = credential.Credential(ak, sk)

        httpProfile = HttpProfile()
        httpProfile.endpoint = "hunyuan.tencentcloudapi.com"
        clientProfile = ClientProfile()
        clientProfile.httpProfile = httpProfile

        params = "{}";
        self.client = CommonClient("hunyuan", "2023-09-01", cred, "", profile=clientProfile)
    def setModel(self,s:str):
        self.model = s
        self.message["Model"] = self.model
    def StreamCall(self,s:str,fn:Callable[[str],None]):
        temp = ""
        if not self.isMulti:
            self.message["Messages"] = []
        self.message["Messages"].append({"Role":"user","Content":f"{s}"})
        resp = self.client.call_sse("ChatCompletions", self.message)
        for chunk in resp:
            ctx = json.loads(chunk["data"])["Choices"][0]["Delta"]["Content"] 
            # ctx = chunk["body"]["result"] 
            try:
                if len(ctx)>0:
                    fn(ctx)
            except Exception as e:
                showMessage("错误",f"{e=}",None,None)
            temp +=ctx   
        if self.isMulti:
            self.history.append({'role': 'system', 'content': f'{temp}'})    

from volcenginesdkarkruntime import Ark
class db:
    def __init__(self,sk=None,ak=None,model=None) -> None:
        if sk==None or ak==None or model==None:
            raise ValueError(f"{sk=},{ak=} is invalid")
        self.client = Ark(ak=ak,sk=sk,base_url="https://ark.cn-beijing.volces.com/api/v3")
        self.model = model
        self.history = []
        self.isMulti =False
    def setModel(self,s:str):
        self.model = s
    def StreamCall(self,s:str,fn:Callable[[str],None]):
        temp = ""
        if not self.isMulti:
            self.history = []
        self.history.append({"role":"user","content":f"{s}"})
        resp:  Stream[ChatCompletionChunk] = self.client.chat.completions.create(model=self.model,messages=self.history,stream=True) # type: ignore
        for chunk in resp:
            if not chunk.choices:
                continue
            ctx: str  = chunk.choices[0].delta.content # type: ignore
            try:
                if len(ctx)>0:
                    fn(ctx)
            except Exception as e:
                showMessage("错误",f"{e=}",None,None)
            temp +=ctx
        if self.isMulti:
            self.history.append({'role': 'system', 'content': f'{temp}'})